package dormouse.vfs.ui;

import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.swing.JPanel;
import javax.swing.JScrollPane;

import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.VFS;

import dormouse.vfs.event.IFileSelectionListener;
import dormouse.vfs.ui.renderers.FileListCanvas;
import dormouse.vfs.ui.renderers.FileListTableBean;
import dormouse.vfs.ui.renderers.IFileListRenderer;

/**
 * This class contains a stack of file list renderers.
 */
@SuppressWarnings("serial")
public class FileRendererCardStack extends JPanel {

	public static final String FILE_LIST_CANVAS = "View As Icons";
	public static final String FILE_LIST_TABLE = "View Details";

	public static final String[] RENDERER_LIST = new String[] {
			FILE_LIST_CANVAS, FILE_LIST_TABLE };

	CardLayout cd = new CardLayout();
	FileListCanvas canvas = null;
	FileListTableBean table = null;

	List<IFileListRenderer<Component>> rendererList = new ArrayList<IFileListRenderer<Component>>(); // @jve:decl-index=0:
	String currentRendererName = null;
	IFileListRenderer<Component> currentRenderer = null;

	Map<String, IFileListRenderer<Component>> rendererMap = new HashMap<String, IFileListRenderer<Component>>();
	FileObject dir = null;
	FileObject selectedFile = null;

	/**
	 * Constructor. This constructor renders the contents of the user's home
	 * directory.
	 * 
	 * @throws FileSystemException
	 *             if there is a problem resolving the home directory.
	 */
	public FileRendererCardStack() throws FileSystemException {
		this(VFS.getManager().resolveFile(System.getProperty("user.home")));
	}

	/**
	 * Constructor
	 * 
	 * @param dir
	 *            the directory to be rendered.
	 */
	public FileRendererCardStack(FileObject dir) {
		this.dir = dir;
		initialize();
	}

	/**
	 * This method adds a file selection listener to the stack.
	 * 
	 * @param fsl
	 *            the listener
	 */
	public void addFileSelectionListener(IFileSelectionListener fsl) {
		Iterator<IFileListRenderer<Component>> it = this.rendererList
				.iterator();
		IFileListRenderer<Component> currRenderer = null;
		while (it.hasNext()) {
			currRenderer = (IFileListRenderer<Component>) it.next();
			currRenderer.addFileSelectionListener(fsl);
		}
	}

	/**
	 * This method initializes this
	 * 
	 */
	private void initialize() {
		this.setLayout(cd);
		canvas = new FileListCanvas(dir);
		canvas.setName(FILE_LIST_CANVAS);
		table = new FileListTableBean(dir);
		table.setName(FILE_LIST_TABLE);

		this.rendererList.add(canvas);
		this.rendererList.add(table);
		rendererMap.put(FILE_LIST_CANVAS, canvas);
		rendererMap.put(FILE_LIST_TABLE, table);

		this.setPreferredSize(new Dimension(200, 200));
		this.add(new JScrollPane(canvas), canvas.getName());
		this.add(new JScrollPane(table), table.getName());

		this.setCurrentRenderer(FILE_LIST_TABLE);

	}

	/**
	 * This method sets the current directory used by the card stack. Each panel
	 * in the card stack is updated with the latest directory.
	 * 
	 * @param dir
	 */
	public void setDirectory(FileObject dir) {
		this.getCurrentRenderer().render(dir, null);
	}

	/**
	 * This method sets the renderers used by the card stack.
	 * 
	 * @param _rendererList
	 */
	public void setRenderers(List<IFileListRenderer<Component>> _rendererList) {
		this.rendererList = _rendererList;
	}

	/**
	 * This method adds a file list renderer to the renderer list.
	 * 
	 * @param renderer
	 * @param rendererName
	 */
	public void addRenderer(IFileListRenderer<Component> renderer,
			String rendererName) {
		this.rendererList.add(renderer);
		this.cd.addLayoutComponent(rendererName, renderer.getComponent());
	}

	/**
	 * This method returns a list of renderers. This list is used to create a
	 * combobox model.
	 * 
	 * @return
	 */
	public List<IFileListRenderer<Component>> getRendererNameList() {
		return this.rendererList;
	}

	public IFileListRenderer<Component> getCurrentRenderer() {
		return (IFileListRenderer<Component>) this.rendererMap
				.get(this.currentRendererName);
	}

	public void setCurrentRenderer(String rendererName) {
		this.currentRendererName = rendererName;
		this.cd.show(this, rendererName);
	}

}
